

import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';

class PlayerWidget extends StatefulWidget {
  final AudioPlayer player;

  const PlayerWidget({
    required this.player,
    super.key,
  });

  @override
  State<StatefulWidget> createState() {
    return _PlayerWidgetState();
  }
}

class _PlayerWidgetState extends State<PlayerWidget> {
  PlayerState? _playerState;
  Duration? _duration;
  Duration? _position;

  StreamSubscription? _durationSubscription;
  StreamSubscription? _positionSubscription;
  StreamSubscription? _playerCompleteSubscription;
  StreamSubscription? _playerStateChangeSubscription;

  bool get _isPlaying => _playerState == PlayerState.playing;
  bool get _isPaused => _playerState == PlayerState.paused;
  Timer? _timer;
  AudioPlayer get player => widget.player;

  @override
  void initState() {
    super.initState();
    _playerState = player.state;
    player.getDuration().then((value) => setState(() {
        _duration = value;
      }),
    );
    player.getCurrentPosition().then((value) => setState(() {
        _position = value;
      }),
    );
    _initStreams();
  }

  @override
  void setState(VoidCallback fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  void dispose() {
    _durationSubscription?.cancel();
    _positionSubscription?.cancel();
    _playerCompleteSubscription?.cancel();
    _playerStateChangeSubscription?.cancel();
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final color = Theme.of(context).primaryColor;
    String timeText = '${_formatTime(_position, _duration)}s';
    return InkWell(
      onTap: (){
        _isPlaying?_stop():_play();
      },
      child: Stack(
        children: [
          Image.asset(
              _isPlaying?
              'images/icon_audio_pause.png':'images/icon_audio_play.png'),
          Positioned(right: 0,child: Container(
            padding: const EdgeInsets.only(right: 18,top: 10),
            child: Text(
              timeText,style: const TextStyle(
              color: Color(0xFF5A55F4),fontSize: 18
            ),),
          ),)
        ],
      ),
    );
  }

  void _initStreams() {
    _durationSubscription = player.onDurationChanged.listen((duration) {
      setState(() => _duration = duration);
    });
    _positionSubscription = player.onPositionChanged.listen(
          (p) => setState(() => _position = p),
    );
    _playerCompleteSubscription = player.onPlayerComplete.listen((event) {
      setState(() {
        _playerState = PlayerState.stopped;
        _position = Duration.zero;
      });
    });
    _playerStateChangeSubscription = player.onPlayerStateChanged.listen((state) {
          setState(() {
            _playerState = state;
          });
        });
  }

  Future<void> _play() async {
    await player.resume();
    setState(() => _playerState = PlayerState.playing);
    _timer = Timer.periodic(const Duration(seconds: 1), (Timer t) {
      player.getCurrentPosition().then((value) {
        setState(() {
          _position = value;
        });
      });
    });
  }

  Future<void> _pause() async {
    await player.pause();
    setState(() => _playerState = PlayerState.paused);
    _timer?.cancel();
  }

  Future<void> _stop() async {
    await player.stop();
    setState(() {
      _playerState = PlayerState.stopped;
      _position = Duration.zero;
    });
    _timer?.cancel();
  }

  String _formatTime(Duration? position, Duration? totalDuration) {
    int positionSeconds = position?.inSeconds ?? 0;
    int totalSeconds = totalDuration?.inSeconds ?? 0;
    return '${(totalSeconds - positionSeconds % 60)}';
  }
}

